package com.cys.markdown.doc.admin.controller.project;

import com.cys.common.data.RespCodeEnum;
import com.cys.common.pojo.RespEntity;
import com.cys.common.util.base.MapUtil;
import com.cys.common.util.base.StringUtil;
import com.cys.markdown.doc.admin.common.annotation.CurrentUser;
import com.cys.markdown.doc.admin.controller.sys.DeptController;
import com.cys.markdown.doc.project.interfaces.entity.IProjectDoc;
import com.cys.markdown.doc.project.interfaces.entity.IProjectInfo;
import com.cys.markdown.doc.project.interfaces.service.ProjectDocService;
import com.cys.markdown.doc.project.interfaces.service.ProjectInfoService;
import com.cys.markdown.doc.project.interfaces.service.ProjectRelUserService;
import com.cys.mid.core.system.interfaces.entity.ISysUser;
import com.cys.mid.core.system.interfaces.service.SysUserService;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/admin/project/info")
@Transactional(rollbackFor = Exception.class)
public class ProjectInfoController {

    private Logger logger = LoggerFactory.getLogger(DeptController.class);

    @Resource(name = "projectInfoServiceImpl")
    private ProjectInfoService projectInfoService;

    @Resource(name = "projectDocServiceImpl")
    private ProjectDocService projectDocService;

    @Resource(name = "sysUserServiceImpl")
    private SysUserService sysUserService;

    /**
     * 根据登录用户id获取项目列表
     *
     * @param sysUserId 登录用户主键
     * @return
     */
    @GetMapping("/getProjectInfoList")
    @ResponseBody
    public RespEntity getProjectInfoList(@CurrentUser Long sysUserId) {
        if (!StringUtil.checkObj(sysUserId)) {
            logger.warn("method[getProjectInfoList] sysUserId is null.");
            return new RespEntity(RespCodeEnum.session_timeout);
        }
        List<IProjectInfo> dataList = projectInfoService.findProjectListBySysUserId(sysUserId);

        return new RespEntity(RespCodeEnum.success, dataList);
    }


    /**
     * 根据登录用户id获取项目分页列表
     *
     * @param pageNo      当前页
     * @param pageSize    当前页显示的数据量
     * @param projectName 项目名称
     * @param sysUserId   登录用户主键
     * @return
     */
    @GetMapping("/getProjectInfoPage")
    @ResponseBody
    public RespEntity getProjectInfoPage(Integer pageNo, Integer pageSize, String projectName, @CurrentUser Long sysUserId) {
        if (!StringUtil.checkObj(sysUserId)) {
            logger.warn("method[getProjectInfoPage] sysUserId is null.");
            return new RespEntity(RespCodeEnum.session_timeout);
        }
        PageInfo<IProjectInfo> pageInfo = projectInfoService.findProjectInfoPage(pageNo, pageSize, projectName, sysUserId);
        return new RespEntity(RespCodeEnum.success, pageInfo);
    }

    /**
     * 根据登录用户id，项目主键，获取文档列表
     *
     * @param pageNo               当前页
     * @param pageSize             当前页显示的数据量
     * @param param-projectInfoId  项目主键
     * @param param-sysUserId      登录用户主键
     * @param param-projectDocName 文档名称
     */
    @GetMapping("/getProjectDocPage")
    @ResponseBody
    public RespEntity getProjectDocPage(Integer pageNo, Integer pageSize, @RequestParam Map param, @CurrentUser Long sysUserId) {
        if (!StringUtil.checkObj(sysUserId)) {
            logger.warn("method[getProjectDocPage] sysUserId is null.");
            return new RespEntity(RespCodeEnum.session_timeout);
        }
        if (!StringUtil.checkObj(param.get("projectInfoId"))) {
            logger.warn("method[getProjectDocPage] projectInfoId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        param.put("sysUserId", sysUserId);
        PageInfo<IProjectDoc> pageInfo = projectDocService.findPageBySysUserId(pageNo, pageSize, param);
        //减少返回前端的数据量
        for (IProjectDoc projectDoc : pageInfo.getList()) {
            projectDoc.setMarkdownDoc("");
            projectDoc.setHtmlValue("");
        }
        return new RespEntity(RespCodeEnum.success, pageInfo);
    }


    /**
     * 根据文档id获取文档资料【需要使用当前登录用户id做校验】
     *
     * @param projectDocId 文档主键
     * @param sysUserId    登录用户主键
     * @return
     */
    @GetMapping("/getProjectDocById")
    @ResponseBody
    public RespEntity getProjectDocById(Long projectDocId, @CurrentUser Long sysUserId) {
        if (!StringUtil.checkObj(sysUserId)) {
            logger.warn("method[getProjectDocById] sysUserId is null.");
            return new RespEntity(RespCodeEnum.session_timeout);
        }
        if (!StringUtil.checkObj(projectDocId)) {
            logger.warn("method[getProjectDocById] projectDocId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        IProjectDoc projectDoc = projectDocService.findBySysUserId(projectDocId, sysUserId);
        return new RespEntity(RespCodeEnum.success, projectDoc);
    }

    /**
     * 新增文档
     *
     * @param param-projectInfoId  工程主键
     * @param param-projectDocName 文档名称
     * @param param-htmlValue      html数据
     * @param param-markdownDoc    markdownDoc 数据
     */
    @PostMapping("/saveDoc")
    @ResponseBody
    public RespEntity saveDoc(@RequestParam Map param, @CurrentUser Long sysUserId) throws Exception {
        if (!StringUtil.checkObj(sysUserId)) {
            logger.warn("method[saveDoc] sysUserId is null.");
            return new RespEntity(RespCodeEnum.session_timeout);
        }
        ISysUser sysUser = sysUserService.find(sysUserId);
        if (!StringUtil.checkObj(sysUser)) {
            logger.warn("method[saveDoc] sysUser is null.");
            return new RespEntity(RespCodeEnum.session_timeout);
        }
        if (!StringUtil.checkObj(param.get("projectInfoId"))) {
            logger.warn("method[saveDoc] projectInfoId is null.");
            return new RespEntity(RespCodeEnum.deficiency, "项目信息不能为空");
        }
        if (!StringUtil.checkObj(param.get("projectDocName"))) {
            logger.warn("method[saveDoc] projectDocName is null.");
            return new RespEntity(RespCodeEnum.deficiency, "文档名称不能为空");
        }
        //用当前操作文档的用户作为作者
        param.put("author", sysUser.getSysUserName());
        //插入新的数据
        IProjectDoc projectDoc = projectDocService.save(param);
        return new RespEntity(RespCodeEnum.success, "保存成功", projectDoc);
    }

    /**
     * 更新文档
     *
     * @param param-projectDocId   文档主键
     * @param param-projectInfoId  工程主键
     * @param param-projectDocName 文档名称
     * @param param-htmlValue      html数据
     * @param param-markdownDoc    markdownDoc 数据
     * @remark 由于文档前端传递的数据量大无法使用PUT，所以改成POST
     */
    @PostMapping("/updateDoc")
    @ResponseBody
    public RespEntity updateDoc(@RequestParam Map param, @CurrentUser Long sysUserId) throws Exception {
        if (!StringUtil.checkObj(sysUserId)) {
            logger.warn("method[updateDoc] sysUserId is null.");
            return new RespEntity(RespCodeEnum.session_timeout);
        }
        ISysUser sysUser = sysUserService.find(sysUserId);
        if (!StringUtil.checkObj(sysUser)) {
            logger.warn("method[updateDoc] sysUser is null.");
            return new RespEntity(RespCodeEnum.session_timeout);
        }
        if (!StringUtil.checkObj(param.get("projectDocId"))) {
            logger.warn("method[updateDoc] projectDocId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        if (!StringUtil.checkObj(param.get("projectInfoId"))) {
            logger.warn("method[updateDoc] projectInfoId is null.");
            return new RespEntity(RespCodeEnum.deficiency, "项目信息不能为空");
        }
        if (!StringUtil.checkObj(param.get("projectDocName"))) {
            logger.warn("method[updateDoc] projectDocName is null.");
            return new RespEntity(RespCodeEnum.deficiency, "文档名称不能为空");
        }
        Long projectDocId = MapUtil.getLong(param, "projectDocId");
        IProjectDoc projectDoc = projectDocService.find(projectDocId);
        if (!StringUtil.checkObj(projectDoc)) {
            logger.warn("method[updateDoc] projectDoc is null. projectDocId :" + projectDocId);
            return new RespEntity(RespCodeEnum.deficiency);
        }
        //先备份数据
        IProjectDoc backup = projectDocService.save(projectDoc);
        //并逻辑删除备份数据
        projectDocService.logicDeleteById(backup.getProjectDocId());
        //用当前操作文档的用户更改为作者
        param.put("author", sysUser.getSysUserName());
        //直接更新原数据
        projectDocService.update(param);

        return new RespEntity(RespCodeEnum.success, "保存成功");
    }

    /**
     * 删除文档
     *
     * @param projectDocId 文档主键
     * @return
     */
    @DeleteMapping("/deleteDoc")
    @ResponseBody
    public RespEntity deleteDoc(Long projectDocId, @CurrentUser Long sysUserId) {
        if (!StringUtil.checkObj(sysUserId)) {
            logger.warn("method[deleteDoc] sysUserId is null.");
            return new RespEntity(RespCodeEnum.session_timeout);
        }
        if (!StringUtil.checkObj(projectDocId)) {
            logger.warn("method[deleteDoc] projectDocId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        logger.info("method[deleteDoc] sysUserId:" + sysUserId + " projectDocId:" + projectDocId);
        projectDocService.logicDeleteById(projectDocId);
        return new RespEntity(RespCodeEnum.success);
    }


    /**
     * 新增子项目
     *
     * @param param-projectParentId    父级主键
     * @param param-projectInfoName    项目名称
     * @param param-projectInfoContent 项目描述
     * @return
     */
    @PostMapping("/saveChildrenProject")
    @ResponseBody
    public RespEntity saveChildrenProject(@RequestParam Map param) throws Exception {
        if (!StringUtil.checkObj(param.get("projectInfoName"))) {
            logger.warn("method[saveChildrenProject] projectInfoName is null.");
            return new RespEntity(RespCodeEnum.deficiency, "请输入子项目名称");
        }
        if (!StringUtil.checkObj(param.get("projectParentId"))) {
            logger.warn("method[saveChildrenProject] projectParentId is null.");
            return new RespEntity(RespCodeEnum.deficiency, "请选择子项目的父级项目");
        }
        IProjectInfo projectInfo = projectInfoService.find(MapUtil.getLong(param, "projectParentId"));
        if (!StringUtil.checkObj(projectInfo)) {
            logger.warn("method[saveChildrenProject] projectInfo is null. projectParentId:" + MapUtil.getLong(param, "projectParentId"));
            return new RespEntity(RespCodeEnum.deficiency, "父级项目不存在");
        }
        if (StringUtil.checkObj(projectInfo.getProjectParentId())) {
            logger.warn("method[saveChildrenProject] 该项目的上级项目是子项目. projectParentId:" + MapUtil.getLong(param, "projectParentId"));
            return new RespEntity(RespCodeEnum.deficiency, "请勿选择子项目");
        }
        projectInfoService.save(param);
        return new RespEntity(RespCodeEnum.success);
    }

    /**
     * 根据项目主键获取项目信息
     *
     * @param projectInfoId 项目主键
     */
    @GetMapping("/getProjectById")
    @ResponseBody
    public RespEntity getProjectById(Long projectInfoId) {
        if (!StringUtil.checkObj(projectInfoId)) {
            return new RespEntity(RespCodeEnum.deficiency);
        }
        IProjectInfo projectInfo = projectInfoService.find(projectInfoId);
        return new RespEntity(RespCodeEnum.success, projectInfo);
    }

    /**
     * 修改子项目
     *
     * @param param-projectInfoId      项目主键
     * @param param-projectInfoName    项目名称
     * @param param-projectInfoContent 项目描述
     * @return
     */
    @PutMapping("/updateChildrenProject")
    @ResponseBody
    public RespEntity updateChildrenProject(@RequestParam Map param) throws Exception {
        if (!StringUtil.checkObj(param.get("projectInfoName"))) {
            logger.warn("method[updateChildrenProject] projectInfoName is null.");
            return new RespEntity(RespCodeEnum.deficiency, "项目名称不能为空");
        }
        if (!StringUtil.checkObj(param.get("projectInfoId"))) {
            logger.warn("method[updateChildrenProject] projectInfoId is null.");
            return new RespEntity(RespCodeEnum.deficiency, "请选择需要修改的子项目");
        }
        IProjectInfo projectInfo = projectInfoService.find(MapUtil.getLong(param, "projectParentId"));
        if (!StringUtil.checkObj(projectInfo)) {
            logger.warn("method[updateChildrenProject] projectInfo is null. projectParentId:" + MapUtil.getLong(param, "projectParentId"));
            return new RespEntity(RespCodeEnum.deficiency, "该子项目不存在");
        }
        if (!StringUtil.checkObj(projectInfo.getProjectParentId())) {
            logger.warn("method[updateChildrenProject] 该项目是父项目. projectParentId:" + MapUtil.getLong(param, "projectParentId"));
            return new RespEntity(RespCodeEnum.deficiency, "请勿选择父级项目修改");
        }
        projectInfo.setProjectInfoName(MapUtil.getString(param, "projectInfoName"));
        projectInfo.setProjectInfoContent(MapUtil.getString(param, "projectInfoContent"));
        projectInfoService.update(projectInfo);
        return new RespEntity(RespCodeEnum.success);
    }

    /**
     * 删除子项目
     *
     * @param projectInfoId 项目主键
     * @return
     */
    @DeleteMapping("/deleteChildrenProject")
    @ResponseBody
    public RespEntity deleteChildrenProject(Long projectInfoId) {
        if (!StringUtil.checkObj(projectInfoId)) {
            logger.warn("method[deleteChildrenProject] projectInfoId is null.");
            return new RespEntity(RespCodeEnum.deficiency);
        }
        IProjectInfo projectInfo = projectInfoService.find(projectInfoId);
        if (!StringUtil.checkObj(projectInfo)) {
            logger.warn("method[deleteChildrenProject] projectInfo is null. projectParentId:" + projectInfoId);
            return new RespEntity(RespCodeEnum.deficiency, "该子项目数据不存在");
        }
        if (!StringUtil.checkObj(projectInfo.getProjectParentId())) {
            logger.warn("method[deleteChildrenProject] 该项目是父项目. projectParentId:" + projectInfoId);
            return new RespEntity(RespCodeEnum.deficiency, "请选择子项目进行删除");
        }
        projectInfoService.logicDeleteById(projectInfoId);
        return new RespEntity(RespCodeEnum.success);
    }


}
